# %%
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
import warnings
warnings.filterwarnings('ignore')

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder

from sklearn.model_selection import train_test_split

# %%
train_path = r"D:/Code/Kaggle/2_HousePrices/input/train.csv"
test_path = r"D:/Code/Kaggle/2_HousePrices/input/test.csv"
train_dataset = pd.read_csv(train_path)
test_dataset = pd.read_csv(test_path)

# %%
train_dataset

# %%
train_dataset.info()

# %%
train_dataset.get("SalePrice").describe()

# %%
f, ax = plt.subplots(figsize=(16, 16))
sns.distplot(train_dataset.get("SalePrice"), kde=False)
plt.show()

# %%
corrmat = train_dataset.corr()
f, ax = plt.subplots(figsize=(16, 16))
sns.heatmap(corrmat, vmax=.8, square=True)

# %%
plt.figure(figsize=(16,16))
columns = corrmat.nlargest(10, 'SalePrice')['SalePrice'].index
correlation_matrix = np.corrcoef(train_dataset[columns].values.T)
sns.set(font_scale=1.25)
heat_map = sns.heatmap(correlation_matrix, cbar=True, annot=True, square=True, fmt='.2f', annot_kws={'size': 10}, yticklabels=columns.values, xticklabels=columns.values)
plt.show()

# %%
total = train_dataset.isna().sum().sort_values(ascending=False)

missing_data = pd.concat([total], axis=1, keys=["Total"])

missing_data.head(30)

# %%
train_dataset = train_dataset.drop((missing_data[missing_data.get("Total") > 1]).index, 1)
train_dataset = train_dataset.drop(train_dataset.loc[train_dataset.get("Electrical").isna()].index)

# %%
train_dataset.isna().sum().max()

# %%
train_dataset.shape

# %%
categories = list(train_dataset.select_dtypes(["object"]))
ct = ColumnTransformer(transformers=[('encoder', OneHotEncoder(), categories)], remainder='passthrough')

# %%
X = train_dataset.drop(['Id', 'SalePrice'], axis=1)
X

# %%
print(X.shape)

# %%
test_dataset = test_dataset.drop((missing_data[missing_data.get("Total") > 1]).index, 1)
print(test_dataset.shape)

# %%
X = ct.fit_transform(X)
X.shape

# %%
test_dataset.info()

# %%
X_test = test_dataset.drop(["Id"], axis=1)

# %%
for i in X_test.isna().columns:
    if X_test.dtypes[i] != "object":
        X_test[i] = X_test[i].fillna(X_test[i].mean())
    else:
        X_test[i] = X_test[i].fillna(X_test[i]. mode()[0])

X_test.shape

# %%
X_test.isna().sum().max()

# %%
X_test = ct.transform(X_test)

# %%
X_test.shape

# %%
y = train_dataset.SalePrice

# %%
X_train, X_val, y_train, y_val = train_test_split(X, y, train_size=0.8, random_state=1)

# %% [markdown]
# LinearRegression model 线性回归模型

# %%
from sklearn.linear_model import LinearRegression

lr_regressor = LinearRegression()
lr_regressor.fit(X_train, y_train)

# %%
y_pred = lr_regressor.predict(X_val)

# %%
lr_regressor.score(X_val, y_val)

# %%
# from sklearn.metrics import mean_squared_error
# print(f"Mean square error: {mean_squared_error(np.log2(y_val), np.log2(y_pred))}")
# print(f"Root mean square error: {mean_squared_error(np.log2(y_val), np.log2(y_pred), squared=False)}")

# %%
y_preds =lr_regressor.predict(X_test)

# %%
y_preds.shape

# %%
test_dataset.Id.shape

# %%
# output = pd.DataFrame({'Id':test_dataset.Id, 'SalePrice':test_preds})
# output.to_csv('submission.csv', index=False)

# %% [markdown]
# DecisionTreeRegressor model 决策树模型

# %%
from sklearn.tree import DecisionTreeRegressor
dt_regressor = DecisionTreeRegressor(max_depth=10, random_state=142)
dt_regressor.fit(X_train, y_train)

# %%
y_preds = dt_regressor.predict(X_test)

# %%
dt_regressor.score(X_val, y_val)

# %%
# output = pd.DataFrame({'Id': test_dataset.Id, 'SalePrice': y_preds})
# output.to_csv('submission.csv', index=False)

# %% [markdown]
# Random Forest Regression 随机森林

# %%
from sklearn.ensemble import RandomForestRegressor

rf_regressor = RandomForestRegressor(max_depth=15, n_estimators=100, random_state=42)
rf_regressor.fit(X, y)

# %%
y_preds = rf_regressor.predict(X_test)

# %%
# output = pd.DataFrame({'Id': test_dataset.Id, 'SalePrice': y_preds})
# output.to_csv('submission.csv', index=False)

# %% [markdown]
# Gradient Boosting

# %%
from sklearn.ensemble import GradientBoostingRegressor

gb_regressor = GradientBoostingRegressor(max_depth=15, n_estimators=100, learning_rate=1.0)
gb_regressor.fit(X, y)

# %%
y_preds = gb_regressor.predict(X_test)

# %%
# output = pd.DataFrame({'Id': test_dataset.Id, 'SalePrice': y_preds})
# output.to_csv('submission.csv', index=False)

# %% [markdown]
# XGBoost

# %%
import xgboost

xgb_regressor = xgboost.XGBRegressor()
xgb_regressor.fit(X, y)

# %%
y_preds = xgb_regressor.predict(X_test)

# %%
# output = pd.DataFrame({'Id': test_dataset.Id, 'SalePrice': y_preds})
# output.to_csv('submission.csv', index=False)

# %% [markdown]
# Ridge Regression 岭回归

# %%
from sklearn.linear_model import Ridge

ridge_regressor = Ridge(alpha=1, solver="auto")
ridge_regressor.fit(X, y)

# %%
ridge_regressor.score(X_val, y_val)

# %%
y_preds = ridge_regressor.predict(X_test)

# %%
# output = pd.DataFrame({'Id': test_dataset.Id, 'SalePrice': y_preds})
# output.to_csv('submission.csv', index=False)

# %% [markdown]
# Lasso Regression

# %%
from sklearn.linear_model import Lasso

alpha_values = np.arange(0, 1, 0.1).tolist()

# %%
max_score = 0
best_alpha_value = 0
for i in alpha_values:
    lasso_regressor = Lasso(alpha=i)
    lasso_regressor.fit(X_train, y_train)
    current_score = lasso_regressor.score(X_val, y_val)
    print(f"Score and alpha value: {current_score}-----{i}")
    if(current_score > max_score):
        max_score = current_score
        best_alpha_value = i
print(max_score, best_alpha_value)

# %%
lasso_regressor = Lasso(alpha=0)
lasso_regressor.fit(X_train, y_train)
lasso_regressor.score(X_val, y_val)

# %%
y_preds = lasso_regressor.predict(X_test)

# %%
# output = pd.DataFrame({'Id': test_dataset.Id, 'SalePrice': y_preds})
# output.to_csv('submission.csv', index=False)

# %% [markdown]
# ElasticNet Regressor 弹性网络回归

# %%
from sklearn.linear_model import ElasticNet

elastic_net_regressor = ElasticNet(alpha=0.1, l1_ratio=0.5)
elastic_net_regressor.fit(X_train, y_train)
elastic_net_regressor.score(X_val, y_val)

# %%
y_preds = elastic_net_regressor.predict(X_test)

# %%
# output = pd.DataFrame({'Id': test_dataset.Id, 'SalePrice': y_preds})
# output.to_csv('submission.csv', index=False)


